package com.mr3chi.horoscopes;

import java.util.Arrays;

import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionLoginBehavior;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.Session.StatusCallback;
import com.facebook.model.GraphUser;
import com.facebook.widget.LoginButton;
import com.mr3chi.horoscopes.R;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

public class ActivityMain extends ActionBarActivity {
	
	//navigation drawer stuff
	private static enum DRAWER_CLOSING_EVENT {NONE, HOROSCROPES_LOAD, TAROTCARD_LOAD, NUMBEROFTHEDAY_LOAD, TODAY_NEWS_LOAD, LOGIN_LOAD, SETTINGS_LOAD};
	private DRAWER_CLOSING_EVENT 	mClosingEvent;
	private int 					mOldPos;
	private DrawerLayout 			mDrawerLayout;
    private ListView 				mDrawerList;
    private ActionBarDrawerToggle 	mDrawerToggle;
    private CharSequence 			mDrawerTitle;
    private CharSequence 			mTitle;
 
    // slide menu items
    private String[] 		navMenuTitles;
    private TypedArray 		navMenuIcons;
    
    //drawer
    private NavDrawerItem[] 			navDrawerItems;
    private NavDrawerListAdapter 		adapter;
    
    private AlertDialog dialog;
    
    //fragments
    private Fragment frHoroscopes 	= null;
    private Fragment frTarotCard	= null;
    private Fragment frNumberOfDay 	= null;
    private Fragment frTodayNews 	= null;

    //Facebook stuff
    FacebookUser 				mFbUser;
    LoginButton					mLoginButton;
    private UiLifecycleHelper 	uiHelper;
    private StatusCallback 		callback = new StatusCallback() {
	    @Override
	    public void call(Session session, SessionState state, Exception exception) {
	        onSessionStateChange(session, state, exception);
	    }
	};
	
	public FacebookUser getInfo(){
		return mFbUser;
	}
	
	//manage facebook session state.
	private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
	    if (state.isOpened()) {
	    	Request request = Request.newMeRequest(session, 
	    	        new Request.GraphUserCallback() {

				@Override
				public void onCompleted(GraphUser user, Response response) {
					if (session == Session.getActiveSession()) {
	    	            if (user != null) {
	    	            	//done
	    	            	readFbUserInfo(user);
	    	            	Toast.makeText(getBaseContext(), "Logged in as " + mFbUser.getFirstName() + " " + mFbUser.getLastName(), Toast.LENGTH_SHORT).show();
	    	            }
	    	        }
				}
	    	});
	    	
	    	request.executeAsync();
	    } else if (state.isClosed()) {
	    	
	    }
	}
	
	//trigger the login fragment
	private void triggerFBLogin(){
		mLoginButton.performClick();
	}
	
	private void readFbUserInfo(GraphUser user){
		mFbUser.setId(user.getId());
		mFbUser.setFirstName(user.getFirstName());
		mFbUser.setMidName(user.getMiddleName());
		mFbUser.setLastName(user.getLastName());
	}
    
	//check if the user is already logged in or not, pop up the reminder if not
    private void checkLogin(){
    	if(!checkFBSession() && hasConnection()){
    		if(((CustomApplication)getApplication()).isRemindAgain()){
    			SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
				boolean stopShowingDialog = settings.getBoolean("setting_popup", false);
				if(!stopShowingDialog){
					if(!dialog.isShowing()){
	        			dialog.show();
	        		}
				}
    		}
    		
		}else{
			if(dialog.isShowing()){
				dialog.dismiss();
			}
		}
    }
    
    private boolean checkFBSession(){
    	Session session = Session.getActiveSession();
    	if(session != null && session.isOpened()){
    		return true;
    	}else{
    		return false;
    	}
    }
    
    //check the internet connection.
    public boolean hasConnection() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(
            Context.CONNECTIVITY_SERVICE);

        NetworkInfo wifiNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (wifiNetwork != null && wifiNetwork.isConnected()) {
          return true;
        }

        NetworkInfo mobileNetwork = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (mobileNetwork != null && mobileNetwork.isConnected()) {
          return true;
        }

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (activeNetwork != null && activeNetwork.isConnected()) {
          return true;
        }

        return false;
    }

	//display the page which our user chosed in the drawer
	private void displayView(int position) {
		
        switch (navDrawerItems[position].getId()) {
        case 11:
        	mClosingEvent = DRAWER_CLOSING_EVENT.HOROSCROPES_LOAD;
        	setTitle(navMenuTitles[0]);
            break;
        case 12:
        	mClosingEvent = DRAWER_CLOSING_EVENT.TAROTCARD_LOAD;
        	setTitle(navMenuTitles[1]);
            break;
        case 13:
        	mClosingEvent = DRAWER_CLOSING_EVENT.NUMBEROFTHEDAY_LOAD;
        	setTitle(navMenuTitles[2]);
            break;
        case 14:
        	mClosingEvent = DRAWER_CLOSING_EVENT.TODAY_NEWS_LOAD;
        	setTitle(navMenuTitles[3]);
            break;
        case 21:
        	mClosingEvent = DRAWER_CLOSING_EVENT.LOGIN_LOAD;
            break;
        case 31:
        	mClosingEvent = DRAWER_CLOSING_EVENT.SETTINGS_LOAD;
            break;
        default:
            break;
        }
        
        // update selected item and title, then close the drawer
        if(!mDrawerLayout.isDrawerOpen(Gravity.START)){
        	mDrawerList.setItemChecked(position, true);
        	mDrawerList.setSelection(position);
        	mOldPos = position;
        	loadFragment();
        	return;
        }else{
        	if((mClosingEvent != DRAWER_CLOSING_EVENT.LOGIN_LOAD) && (mClosingEvent != DRAWER_CLOSING_EVENT.SETTINGS_LOAD)){
            	mDrawerList.setItemChecked(position, true);
            	mDrawerList.setSelection(position);
                mOldPos = position;
            }else{
            	mDrawerList.setItemChecked(mOldPos, true);
            	mDrawerList.setSelection(mOldPos);
            }
        	mDrawerLayout.closeDrawer(mDrawerList);
        }
	}
    
    private void loadFragment(){
    	getSupportActionBar().setTitle(mTitle);
    	Fragment fragment = null;
    	switch (mClosingEvent) {
		case HOROSCROPES_LOAD:
			if(frHoroscopes == null){
				frHoroscopes = new FragmentHoroscopes();
        	}
        	fragment = frHoroscopes;
			break;
		case TAROTCARD_LOAD:
			if(frTarotCard == null){
				frTarotCard = new FragmentTarotCard();
        	}
        	fragment = frTarotCard;	
			break;
		case NUMBEROFTHEDAY_LOAD:
			frNumberOfDay = new FragmentNumberOfDay();
        	fragment = frNumberOfDay;	
			break;
		case TODAY_NEWS_LOAD:
			frTodayNews = new FragmentTodayNews();
        	fragment = frTodayNews;				
			break;
		case LOGIN_LOAD:
			
			Session session = Session.getActiveSession();
            if(session != null && session.isOpened()){
            	Session.getActiveSession().closeAndClearTokenInformation();
            }else{
            	if(hasConnection()){
            		triggerFBLogin();
            	}
            	else{
    				Toast.makeText(this, R.string.error_no_intenet_connection, Toast.LENGTH_SHORT).show();
    			}
            }
			
			break;
		case SETTINGS_LOAD:
			Intent intent = new Intent(this, ActivitySettings.class);
			startActivity(intent);
			break;
		
		default:
			break;
		}
    	
    	if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
        }
    	
    	mClosingEvent = DRAWER_CLOSING_EVENT.NONE;
    }
    
    //activity oncreate method
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mFbUser = new FacebookUser();
		
		uiHelper = new UiLifecycleHelper(this, callback);
	    uiHelper.onCreate(savedInstanceState);
	    
		mLoginButton = (LoginButton) findViewById(R.id.fb_login_button);
		mLoginButton.setSessionStatusCallback(callback);
		mLoginButton.setReadPermissions(Arrays.asList("public_profile", "email" ));
		//using webview for logging in in debug version
		mLoginButton.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
		
	    mClosingEvent = DRAWER_CLOSING_EVENT.NONE;
	    
		mTitle = mDrawerTitle = getTitle();
		navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
		navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
		
		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
        
        navDrawerItems = new NavDrawerItem[]{
        		NavMenuSection.create(10, getResources().getString(R.string.section_daily)),
        		NavMenuItem.create(11, navMenuTitles[0], 0, navMenuIcons.getResourceId(0, -1), false, this),
        		NavMenuItem.create(12, navMenuTitles[1], 0, navMenuIcons.getResourceId(1, -1), false, this),
        		NavMenuItem.create(13, navMenuTitles[2], 0, navMenuIcons.getResourceId(2, -1), false, this),
        		NavMenuItem.create(14, navMenuTitles[3], 0, navMenuIcons.getResourceId(3, -1), false, this),
        		NavMenuSection.create(20, getResources().getString(R.string.section_facebook)),
        		NavMenuItem.create(21, navMenuTitles[4], 0, navMenuIcons.getResourceId(4, -1), false, this),
        		NavMenuSection.create(30, getResources().getString(R.string.section_setting)),
        		NavMenuItem.create(31, navMenuTitles[5], 0, navMenuIcons.getResourceId(5, -1), false, this),
        };
        navMenuIcons.recycle();
        
        adapter = new NavDrawerListAdapter(this, R.layout.item_drawer_item, navDrawerItems);
        mDrawerList.setAdapter(adapter);
        
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer,
                R.string.action_settings, // nav drawer open - description for accessibility
                R.string.action_settings // nav drawer close - description for accessibility
        ){
            public void onDrawerClosed(View view) {
            	loadFragment();
                supportInvalidateOptionsMenu();
            }
 
            public void onDrawerOpened(View drawerView) {
                getSupportActionBar().setTitle(mDrawerTitle);
                supportInvalidateOptionsMenu();
            }

			@Override
			public void onDrawerStateChanged(int newState) {
				super.onDrawerStateChanged(newState);
				if (newState == DrawerLayout.STATE_SETTLING) {
		            if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
		                // starts opening
		            	//check if user logged in or not for changing text :#
		            	Session session = Session.getActiveSession();
		                if(session != null && session.isOpened()){
		                	
		                	((NavMenuItem)navDrawerItems[6]).setLabel("Log out");
		                	
		                }else{
		                	((NavMenuItem)navDrawerItems[6]).setLabel("Log in");
		                }
		                adapter.notifyDataSetChanged();
		            } else {
		                // closing drawer
		            }
		            supportInvalidateOptionsMenu();
		        }
			}
        };
        
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        mDrawerList.setOnItemClickListener(new DrawerClickListener());
        
        //display horoscopes first
        if(savedInstanceState == null){
        	displayView(1);
            mOldPos = 1;
        }else{
        	
        	int value = savedInstanceState.getInt("output_page");
        	if(value>0){
        		displayView(value);
        	}
        }
        
        
        //create dialog
        AlertDialog.Builder builder = new Builder(this);
		builder.setTitle("You are Not Currently Logged In");
		builder.setMessage("Do you want to log in with your Facebook account?");
		builder.setPositiveButton(R.string.dialog_yes, new OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				triggerFBLogin();
			}
		});
		builder.setNegativeButton(R.string.dialog_no, new OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				((CustomApplication)getApplication()).setRemindAgain(false);
			}
		});
		
		builder.setNeutralButton(R.string.dialog_remindlater, new OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				((CustomApplication)getApplication()).setRemindAgain(true);
			}
		});
		dialog = builder.create();
	}
	
	//inflate menu
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);

	    return super.onCreateOptionsMenu(menu);
	}

	//menu click-event handler
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle action bar actions click
        switch (item.getItemId()) {
        
        default:
            return super.onOptionsItemSelected(item);
        }
	}
	
	@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onPrepareOptionsMenu(menu);
    }
	
    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getSupportActionBar().setTitle(mTitle);
    }
    
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }
 
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
    
    private class DrawerClickListener implements ListView.OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
		        long id) {
		    displayView(position);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		uiHelper.onResume();
		checkLogin();
		
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		uiHelper.onPause();
	}
	
	

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		uiHelper.onDestroy();
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		uiHelper.onSaveInstanceState(outState);
		outState.putInt("output_page", mOldPos);
	}
    
}
